;------------------------------------------------------------------------------
;
; As yet untitled
; The Calodox 1k ZX81 Intro
; Copyright (c) 2003 Sebastian Gerlach
;
; 3. Skyscroller
;
; Presents a scrolling starfield with text fade-in/fade-out.
;
; ThreeHeads logo by Fred
;
;------------------------------------------------------------------------------

.z80            ;use Z80 instruction set

org 4034h

	starcount equ  76

; Code starts at 4034h

start_here:
	ld ix, traceproc
	ld sp, 43feh
	
	ld hl, fontmem		; Initialize star positions
	ld de, fontmem+1
	ld (hl), 0
	ld bc, 111
	ldir

	out (0feh), a
	
loop_around:

	ld hl, lflag
	xor a
	ld (hl), a
tag:
	or (hl)
	jr z, tag
	
	ld l, incmod	; h is identical to lflag
	ld a, 3ch		; 3c = inc a / af = xor a / 93=3c^af
	xor (hl)
	ld (hl), a
	
	ld hl, (frames)
	inc hl
	ld (frames), hl

modfinal2:	
	ld a, 1
	cp h
jmpfinal:
	jr c, normal			; change to 9ch for final
	bit 0, l
	jr nz, loop_around
	
;-------------------------------------------------
; addstars
; Add stars to view
;-------------------------------------------------
addstars:
	ld h, 42h
	ld a, (spos)
	add 41
	ld (spos), a
	ld l, a

	cp starpos+1
	jr c, loop_around
	cp starpos+starcount
	jr nc, loop_around

	ld a, (vpos)
	add 121
;	rlca
	ld (vpos), a
	and 127
modadd:
	ld (hl), a
	or h		; is 180, since the ld (hl), a above
				; is swapped for ld (hl), imm. later
	jr loop_around

normal:
	ld a, starcount
	bit 0, l
	jr z, ndisp
	ld a, (posy)
ndisp:
	ld (inneroff), a
	
	ld a, l
	and 3
	jr nz, noup
	ld a, (posy)
	cp 71
	jr c,good
	xor a
good:
	inc a
	ld (posy), a

	ld a, (posx)
	inc a
	cp 140
	jr c,good2
	xor a
good2:
	ld (posx), a
	
noup:	

	ld a, (frames)
	and 127
	jr nz, ldone


	ld hl, (textptr)
	ld a, (hl)
	ld (posx), a
	inc l
	ld a, (hl)
	ld (posy), a
	inc l
	
	ld a, (moddisproc+1)
	xor 43h
	ld (moddisproc+1), a
	
	ld de, 7400h
	jp pe, vload

	and (hl)
	jr z, lasttext
	
	call loadchars
	inc l
	ld (textptr), hl
	ld de, 3878h
	
vload:
	ld (vidparm),de
	xor a
ldone:


	ld de, (vidparm)
	
	cp 64
	ld a,6fh
	jr c,flow
	ld a,2eh
	ld de, 7400h
flow:
	ld (modl0),a

;-------------------------------------------------
; prepchars
; Update some character bits
; Mod: a, bc
;-------------------------------------------------
	ld b, 7				; Copy 7 bytes
nval:
	ld a, (spos)		; Current copy position
	add 37				; Add some prime number
	ld (spos), a		; Store result
	cp d				; Compare with size of buffer
	jr nc, valnok		; If larger, ignore this byte
	add e				; Add memory offset to source
	ld h, 43h			; High byte of hl
modl0:	
	ld l, a				; Low byte of hl  ; ld l,imm. (2eh) or ld l,a (6fh)
	nop					; Zero for mod prev
	ld c, (hl)			; Load source byte
	add d				; Adjust to destination
	ld l, a				; Low byte of hl
	ld (hl), c			; Store byte
valnok:
	djnz nval			; Loop until done
sloop_around:
	jp loop_around
	
lasttext:
	ld a, 10
	ld (modfinal2+1), a
	ld a, 36h
	ld (modadd), a
	ld a, 9ch
	ld (jmpfinal+1), a
	jr sloop_around
	
	
;-------------------------------------------------
; loadchars
; Load a string into character memory
; Mod: a, bc
; In: hl - pointer to text
;-------------------------------------------------
loadchars:
	ld de, fontmem		; Destination bitmap pointer
nextchar:
	ld a, (hl)			; Load char from string
	or a				; Test if zero
	ret z				; If zero, quit
	inc l				; Increment string pointer
	push hl				; Store it for future reference
	
	ld h, 0fh			; Will be 1e or 1f later to access ROM char table
	rlca				; Rotate and clear carry (MSB is always 0)
	rla					; Rotate through carry
	rla					; Rotate through carry (highest bit of char is now in carry
	rl h				; Shift in carry to h (h is now 1e or 1f)
	ld l, a				; Keep rest in l
	inc l				; Skip first line of char
	
	ld b, 7				; Copy 7 lines of character
loadcharline:
	ld a, (hl)			;  7 Load line
	ld c, a				;  4 Copy line
	rrca				;  4 Shift original line
	or c				;  4 Or them together (thickens char)
	ld (de), a			;  7 Store result
	ld a, 8				;  7 Update position in de
	add e				;  4
	ld e, a				;  4
	inc l				;  4 Increment hl
	djnz loadcharline	; 13 Load next line
	ld a, -55			; Move back to top of next column
	add e				
	ld e, a
	pop hl				; Recover string pointer
	jr nextchar			; Loop until done

;-------------------------------------------------
; drawproc
; Render display
;-------------------------------------------------
drawproc:
	ld hl, starpos

	ld a, (hl)			; Delay before first line
	add 73+10
	call delay
	
	ld a, (inneroff)
	ld b, a
	
continue:

	ld ix, endofline
	ld a, h					; h already contains 42h
	ld i, a
nextline:
	ld a, l
	and 3
	jp oneline+8000h		; 10
oneline:	
	ld r,a					; 9
	
lflag:
	db 0					; Place lflag here, since it will never have bit 6 at one

    jp ix					; 8
endofline:
	ld a, 191
	sub (hl)
	inc l
	push af
	ld a, l
	and 3
incmod:
	inc a
;	xor a
	ld d, a
	ld a, (hl)
	cp 180			; 7
	jr z, skipdis
	sub d		; 4
	jr nc,dok	; 7
	add 180		; 7
	jr dol		; 12
skipdis:
	ld a, (hl)
	nop
dok:			; 12
	ld c,(hl)	; 7
	ld c,(hl)	; 7
dol:
	ld (hl), a
	ld c, a
	pop af
	add c
	exx
	call delay

	ld b, 5
blu:djnz blu
	exx

	dec b
	jr nz, nextline
	
	ld a, starpos+starcount
	cp l
	jr z, final

	ld a, 180	
	sub (hl)
	ld b, a
	ld a, (posx)
	add b
	call delay
	
	ld a, 43h
	ld i, a
moddisproc:
	jp dodis		; 41b0 or 41f3
	
	defs 41b0h-$	; To ensure address of this label
					; has an appropriate parity
dodis:
	ld c, 14
	ld a, vidmem
	ld ix, endofline2
nextline2:
	jp oneline2+8000h						; 10
oneline2:	
	ld r,a									; 9
	db 0,0,0,0, 0,0,0,0
    jp ix									; 8
endofline2:
	dec c
	jr z, flog
	bit 0, c
	jr nz, fog
	add 8
	jr fjd
fog:
	ld b,(hl)
	ld b,(hl)
fjd:
	ld b,(hl)			; 7w
	nop					; 4w
	ld b, 6				; 7w
dfg:djnz dfg			; 13w
	
	jr nextline2		; 13
flog:	
	
	ld a, 6
	add l
	ld l, a

dodisend:
	ld a, (posx)
	ld b, a
	ld a, 230
	sub b
	add (hl)
	call delay

	ld a, starpos+starcount
	sub l
	ld b, a
	jp continue


;-------------------------------------------------
; Don't touch this value! It's parity was
; carefully studied :-)
;-------------------------------------------------
	defs 41f3h-$
dodis2:
	ld c, 29
	ld a, 74h
	ld ix, endofline3

	jp oneline3+8000h						; 10
oneline3:	
	ld r,a									; 9
;-------------------------------------------------
; Framebuffer for stars
; Must be located at 4200h
; This is achieved by carefully placing preceding
; code :-)
;-------------------------------------------------
	db 1,3,7,15

	jp ix									; 8
	
final:
	ld hl, lflag
	ld (hl), 1		; Allow main loop to run
	ld ix, traceproc
	jr doret
	
endofline3:
	dec c
	jr z, flog2
	add 4
	ld b, 10				; 7w
dfg2:djnz dfg2				; 13w
	ld b,(hl)				; 7w
	ld b,(hl)				; 7w
	
	jp oneline3+8000h						; 10
flog2:	
	nop
	ld a, 11 
	add l
	ld l, a
	jr dodisend	


traceproc:
	in a, (0feh)
	ld b, 80
here:	djnz here
	
	ld ix, drawproc
	out (0ffh),a
doret:
	ld a, 36
	jp 029eh
	
	
;-------------------------------------------------
; Variables part 2
;-------------------------------------------------
frames		dw 00h
textptr		dw text
vpos		db 45
spos		db 73	
inneroff	db starcount
posy		db 1
posx		db 2

vidparm		dw 3878h	

	

	
;-------------------------------------------------
; delay
; Delay for a+144 clock cycles (call: 17)
; Carry adds 256 cycles
; Mod: a, bc
;-------------------------------------------------
delay:
	jr nc, shortdelay
	; 5+256 to go
	nop
	nop
	nop
	ld b, 19
dsjf:djnz dsjf
shortdelay:
	ld b, a			; 4
	and 3			; 7
	add insts		; 7
	ld (modme+1), a ; 13
modme:
	ld a, (insts)	; 13
	ld (strt), a	; 13
strt:
	nop				; 4			61
	
	srl b			; 8
	srl b			; 8
	ld a, b 		; 4
	cpl				; 4
	and 3			; 7
	ld (jop-1), a	; 13
	jr jop			; 12		117
jop:
	nop
	nop
	nop	
	srl b			; 8
	srl b			; 8
	ret z			; 11		144
	; Missing 6 cycles because ret not taken
loophere:
	dec b
	jr nz, loophere
	; Missing another 5 cycles because of last jr not taken
	ret z 
	; Takes the 11 cycles we have left :-)
	; Simply ret would have been one cycle too fast for us here

	
insts:
	nop			; 4
	ret c		; 5
	inc bc		; 6
	ld a,(bc)	; 7
	
text:
db 30,30
db 28h,34h,29h,2ah,0
db 80,1
db 32h,2eh,33h,26h,38h,0
db 1,10
db 2ch,37h,26h,35h,2dh,2eh,3dh,0
db 50,16
db 2bh,37h,2ah,29h,0
db 20,25
db 32h,3ah,38h,2eh,28h,0
db 50,30
db 33h,34h,33h,2ah,0eh,16h,11h,0
db 10,10,0
db 0
db 0,0,0,0,0
	

;-------------------------------------------------
; Star positions. First star must be invisible.
;-------------------------------------------------
starpos:
	db 180,180,180,180,180,180,180,180
	db 180,180,180,180,180,180,180,180
	db 180,180,180,180,180,180,180,180
	db 180,180,180,180,180,180,180,180
	db 180,180,180,180,180,180,180,180
	db 180,180,180,180,180,180,180,180
	db 180,180,180,180,180,180,180,180
	db 180,180,180,180,180,180,180,180
	db 180,180,180,180,180,180,180,180
	db 180,180,180,180,0
	
	defs 4300h-$
;-------------------------------------------------
; ThreeHeads logo by fred
;-------------------------------------------------
	db   0,  0,  0,  0,  0, 15,248,  0
	db   0, 63,254,  0,  0,255,255,128
	db   1,255,255,192,  3,255, 15,224
	db   7,252,  7,240, 15,252,  3,248
	db  31,252,  3,252, 63,222,  3,252
	db  63, 14,  3,252, 63, 14,  7,254
	db 127, 14,  7,254,126, 14,  4, 62
	db 126, 15, 12, 62,127, 15, 28, 62
	db 255,142, 60, 62,255,134, 28, 62
	db 127,132, 28,126,127,132, 25,254
	db  63,  0, 17,254, 30,  0,  1,254
	db  30,  0,  0,254, 14,  0,  0,255
	db  15,  0,  0,255,  7,  0,  0,255
	db   2,  0,  0,254,  0,  0,  1,192
	db   0,  0,  1,128


.comment otherbmp
db 0,0,112,0,0,1,252,0
db 0,3,254,0,0,7,255,0
db 0,15,255,0,0,15,255,128
db 0,15,255,128,2,7,255,128
db 15,135,255,128,31,195,255,128
db 31,193,255,0,63,199,255,0
db 63,131,252,8,63,131,254,60
db 127,131,254,126,127,129,252,254
db 63,128,248,254,15,129,240,255
db 15,195,224,255,7,199,224,254
db 7,199,240,124,7,239,240,248
db 15,239,241,240,31,239,243,224
db 63,239,243,192,63,255,247,192
db 63,255,255,224,127,255,255,224
db 127,255,255,240
.comment otherbmp

fontmem equ 4378h
vidmem equ 43b0h

end start_here
